home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / dpmigcc5.zip / RSX / SOURCE / START32.C < prev    next >
C/C++ Source or Header  |  1994-12-12  |  13KB  |  396 lines

  1. /*****************************************************************************
  2.  * FILE: start32                                 *
  3.  *                                         *
  4.  * DESC:                                     *
  5.  *    - DPMI-switches for DPMI 0.9                         *
  6.  *    - init some protected mode interrupts                     *
  7.  *    - init exception handlers                         *
  8.  *    - clean up for exit                             *
  9.  *                                         *
  10.  * Copyright (C) 1993,1994                             *
  11.  *    Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld             *
  12.  *    email: rainer@mathematik.uni-bielefeld.de                 *
  13.  *                                         *
  14.  *****************************************************************************/
  15.  
  16. #include "DPMI.H"
  17. #include "DPMI10.H"
  18. #include "PRINTF.H"
  19. #include "PROCESS.H"
  20. #include "RSX.H"
  21. #include "ADOSX32.H"
  22. #include "CDOSX32.H"
  23. #include "EXCEP32.H"
  24. #include "START32.H"
  25. #include "COPY32.H"
  26. #include "SYSDEP.H"
  27.  
  28. /* global extender segments,selectors */
  29. UINT cs16real, ds16real;    /* 16-bit segments for extender */
  30. UINT code16sel, data16sel;    /* 16-bit cs,ds for extender */
  31. UINT stack16sel;        /* 16-bit stack sel */
  32. DWORD stackp16;         /* 16-bit stack offset (use long!) */
  33. UINT sel_incr;            /* increment to next selector */
  34. UINT dosmem_sel;        /* selector for the first MB */
  35. UINT fpu_status;
  36. WORD DPMIversion = 0;
  37. WORD previous_client_cs;
  38.  
  39. char dpmi10;            /* DPMI 1.0 server */
  40. char dpmi10_map;        /* DPMI 1.0 mapping supported */
  41. char dpmi10_page;        /* DPMI 1.0 access/dirty supported */
  42. char dpmi10_zero;        /* DPMI 1.0 demand zero supported */
  43.  
  44. /* private vars */
  45. static WORD DPMIdata_para_needed;
  46. static WORD DPMIdata_segm_address;
  47. static char fpu_status_init;
  48.  
  49. /*
  50. ** back to real-mode, terminate ( int0x21 must set to orginal )
  51. */
  52. #ifndef __EMX__
  53. extern void ProtectedModeSwitch(void);
  54. extern void RealModeSwitch(void);
  55. extern void _cexit(void);
  56. #endif
  57.  
  58. void protected_to_real(WORD errorlevel)
  59. {
  60.     if (fpu_status_init)
  61.     DpmiSetCoproStatus(fpu_status & 3);
  62.  
  63. #ifdef _MSC_VER
  64.     RealModeSwitch();        /* clean up in real mode */
  65.     _cexit();
  66.     ProtectedModeSwitch();
  67. #endif
  68. #ifdef _TURBOC_
  69.     RealModeSwitch();        /* clean up interrupt vector */
  70.     _restorezero();
  71.     ProtectedModeSwitch();
  72. #endif
  73.  
  74.     dos_exit(errorlevel);
  75.     /* program ends here */
  76. }
  77.  
  78. void init_real_mode(void)
  79. {
  80. #ifdef __EMX__
  81.     DWORD base_addr;    /* rsx32 is in protected mode */
  82.  
  83.     code16sel = GetCS();
  84.     data16sel = stack16sel = GetDS();
  85.  
  86.     GetBaseAddress(code16sel, &base_addr);
  87.     cs16real = (UINT) (base_addr >> 4);
  88.     GetBaseAddress(data16sel, &base_addr);
  89.     ds16real = (UINT) (base_addr >> 4);
  90.  
  91. #else            /* rsx16 is in real mode */
  92.     cs16real = GetCS();
  93.     ds16real = GetDS();
  94. #endif
  95. }
  96.  
  97. /*
  98. ** switch to protected-mode via DPMI-host
  99. */
  100. int real_to_protected(WORD mode)
  101. {
  102. #ifndef __EMX__
  103.     WORD DPMIflags;
  104.     BYTE processor;
  105.     DWORD PM_jump;        /* switch to protmode jump */
  106.  
  107.     clearregs();
  108.     /* setbuf(stdout,NULL); */
  109.  
  110.     if (GetDpmiEntryPoint(&PM_jump, &DPMIdata_para_needed,
  111.               &DPMIflags, &DPMIversion, &processor)) {
  112.     puts("No DPMI-host found!");
  113.     return -1;
  114.     }
  115.     if (mode == 1 && !(DPMIflags & 1)) {
  116.     puts("32bit programs not supported\n");
  117.     return -1;
  118.     }
  119.     if (DPMIdata_para_needed) { /* get DPMI ring 0 stack */
  120.     DPMIdata_segm_address = GetDpmiHostParagraph(DPMIdata_para_needed);
  121.     if (!DPMIdata_segm_address) {
  122.         puts("Can't alloc memory for the DPMI-host-stack");
  123.         return -1;
  124.     }
  125.     }
  126.     if (DpmiEnterProtectedMode(PM_jump, mode, DPMIdata_segm_address)) {
  127.     puts("can't switch to Protected Mode");
  128.     return -1;
  129.     }
  130.     /* Now we are in Protected Mode */
  131.  
  132.     /* lock DPMI-stack */
  133.     if (DPMIdata_para_needed) {
  134.     LockLinRegion((DWORD) DPMIdata_segm_address << 4,
  135.               (DWORD) DPMIdata_para_needed << 4);
  136.     }
  137.     /* get prot-mode extender segments */
  138.     code16sel = GetCS();
  139.     data16sel = stack16sel = GetDS();
  140. #endif
  141.     return 0;
  142. }
  143.  
  144. /*
  145. ** test DPMI server
  146. */
  147. int test_dpmi_capabilities(void)
  148. {
  149.     if (!DPMIversion) {
  150.     DPMIVERSION ver;
  151.  
  152.     GetDPMIVersion(&ver);
  153.     DPMIversion = ((WORD)ver.major << 8) | ver.minor;
  154.  
  155.     if (opt_printall)
  156.         printf("DPMI version %d.%d\n", ver.major, ver.minor);
  157.     }
  158.  
  159.     if (!opt_force_dpmi09) {
  160.     DPMICAP cap;
  161.     if ((DPMIversion >> 8) >= 1)
  162.         dpmi10 = 1;
  163.     if (!GetDPMICapabilities(&cap, iobuf)) {
  164.         if (cap.bits & 1)
  165.         dpmi10_page = 1;
  166.         if (cap.bits & 8)
  167.         dpmi10_map = 1;
  168.         if (cap.bits & 16)
  169.         dpmi10_zero = 1;
  170.         if (dpmi10_page & dpmi10_map)    /* give 0.9x a chance */
  171.         dpmi10 = 1;
  172.     }
  173.     }
  174.  
  175.     sel_incr = SelInc();
  176.  
  177.     /* build selector for first megabyte */
  178.     AllocLDT(1, &dosmem_sel);
  179.     SetBaseAddress(dosmem_sel, 0L);
  180.     SetAccess(dosmem_sel, APP_DATA_SEL, BIG_BIT | GRANULAR_BIT);
  181.     SetLimit(dosmem_sel, 1024L * 1024L - 1L);
  182.  
  183.     return 0;
  184. }
  185.  
  186. static POINTER16_32 int21v;    /* old int21h handler address */
  187. static POINTER16_32 int10v;    /* old int10h handler address */
  188. static POINTER16_32 int33v;    /* old int33h handler address */
  189. static POINTER16_32 ctrlcv;    /* old control-c handler */
  190. static POINTER16_32 timerv;    /* old timer handler */
  191. static POINTER16_32 debintv;    /* old int3 handler */
  192. static POINTER16_32 excep0v, excep1v, excep2v, excep3v, excep4v, excep5v,
  193.  excep6v, excep7v, excep8v, excep9v, excep10v, excep11v, excep12v, excep13v, excep14v,
  194.  excep15v, excep16v, excep17v;
  195.  
  196. int hangin21;
  197.  
  198. int hangin_extender(void)
  199. {
  200.     UINT alias_cs;
  201.     int stackp;
  202.  
  203.     /* entry stack for interrupts, exceptions */
  204.     stackp16 = (UINT) & stackp;
  205.  
  206.     /* store ds-sel in code for some interrupt handler */
  207.     if (CreatAlias(code16sel, &alias_cs))
  208.     return -1;
  209.  
  210.     /* store 16bit data selector in load_ds function */
  211.     store32(alias_cs, (DWORD) (UINT) extender_ds, (DWORD) data16sel);
  212.  
  213.     /* hang in int 0x21 */
  214.     if (GetProtModeVector32(0x21, &int21v.sel, &int21v.off) == -1) {
  215.     puts("error:can't get int21");
  216.     return -1;
  217.     }
  218.     if (SetProtModeVector32(0x21, code16sel, (DWORD) (UINT) doscall) == -1) {
  219.     puts("error:can't set int21");
  220.     return -1;
  221.     }
  222.     hangin21 = 1;
  223.     previous_client_cs = int21v.sel;
  224.     align_iobuf();
  225.  
  226.     /* chain to default int 0x21 */
  227.     store32(alias_cs, (DWORD) (unsigned) &int21vsel, (DWORD) int21v.sel);
  228.     store32(alias_cs, (DWORD) (unsigned) &int21voff, (DWORD) int21v.off);
  229.  
  230.     /* set new bios int10 for vesa calls */
  231.     if (GetProtModeVector32(0x10, &int10v.sel, &int10v.off)<0)
  232.     puts("int10 fail:get");
  233.     if (SetProtModeVector32(0x10, code16sel, (DWORD) (UINT) bioscall)<0)
  234.     puts("int10 fail:set");
  235.     store32(alias_cs, (DWORD) (unsigned) &int10vsel, (DWORD) int10v.sel);
  236.     store32(alias_cs, (DWORD) (unsigned) &int10voff, (DWORD) int10v.off);
  237.  
  238.     FreeLDT(alias_cs);
  239.  
  240.     /* MOUSE */
  241.     GetProtModeVector32(0x33, &int33v.sel, &int33v.off);
  242.     SetProtModeVector32(0x33, code16sel, (DWORD) (UINT) mousecall);
  243.  
  244.  
  245.     /* get all exception vectors */
  246.     GetExceptionVector32(0, &excep0v.sel, &excep0v.off);
  247.     GetExceptionVector32(1, &excep1v.sel, &excep1v.off);
  248.     GetExceptionVector32(2, &excep2v.sel, &excep2v.off);
  249.     GetExceptionVector32(3, &excep3v.sel, &excep3v.off);
  250.     GetExceptionVector32(4, &excep4v.sel, &excep4v.off);
  251.     GetExceptionVector32(5, &excep5v.sel, &excep5v.off);
  252.     GetExceptionVector32(6, &excep6v.sel, &excep6v.off);
  253.     GetExceptionVector32(7, &excep7v.sel, &excep7v.off);
  254.     GetExceptionVector32(8, &excep8v.sel, &excep8v.off);
  255.     GetExceptionVector32(9, &excep9v.sel, &excep9v.off);
  256.     GetExceptionVector32(10, &excep10v.sel, &excep10v.off);
  257.     GetExceptionVector32(11, &excep11v.sel, &excep11v.off);
  258.     GetExceptionVector32(12, &excep12v.sel, &excep12v.off);
  259.     GetExceptionVector32(13, &excep13v.sel, &excep13v.off);
  260.     GetExceptionVector32(14, &excep14v.sel, &excep14v.off);
  261.     GetExceptionVector32(15, &excep15v.sel, &excep15v.off);
  262.     GetExceptionVector32(16, &excep16v.sel, &excep16v.off);
  263.     GetExceptionVector32(17, &excep17v.sel, &excep17v.off);
  264.  
  265.     /* set all exception vectors */
  266.     if (!opt_debugrsx) {
  267.     SetExceptionVector32(1, code16sel, (DWORD) (UINT) (excep1_386));
  268.     SetExceptionVector32(3, code16sel, (DWORD) (UINT) (excep3_386));
  269.     }
  270.     SetExceptionVector32(0, code16sel, (DWORD) (UINT) (excep0_386));
  271.     SetExceptionVector32(2, code16sel, (DWORD) (UINT) (excep2_386));
  272.     SetExceptionVector32(4, code16sel, (DWORD) (UINT) (excep4_386));
  273.     SetExceptionVector32(5, code16sel, (DWORD) (UINT) (excep5_386));
  274.     SetExceptionVector32(6, code16sel, (DWORD) (UINT) (excep6_386));
  275.     SetExceptionVector32(7, code16sel, (DWORD) (UINT) (excep7_386));
  276.     SetExceptionVector32(8, code16sel, (DWORD) (UINT) (excep8_386));
  277.     SetExceptionVector32(9, code16sel, (DWORD) (UINT) (excep9_386));
  278.     SetExceptionVector32(10, code16sel, (DWORD) (UINT) (excep10_386));
  279.     SetExceptionVector32(11, code16sel, (DWORD) (UINT) (excep11_386));
  280.     SetExceptionVector32(12, code16sel, (DWORD) (UINT) (excep12_386));
  281.     SetExceptionVector32(13, code16sel, (DWORD) (UINT) (excep13_386));
  282.     SetExceptionVector32(15, code16sel, (DWORD) (UINT) (excep15_386));
  283.     SetExceptionVector32(16, code16sel, (DWORD) (UINT) (excep16_386));
  284.     SetExceptionVector32(17, code16sel, (DWORD) (UINT) (excep17_386));
  285.     if (dpmi10)
  286.     SetExceptionVector32(14, code16sel, (DWORD) (UINT) (page_fault));
  287.     else
  288.     SetExceptionVector32(14, code16sel, (DWORD) (UINT) (excep14_386));
  289.  
  290.     /* TIMER */
  291.     GetProtModeVector32(0x1C, &timerv.sel, &timerv.off);
  292.     SetProtModeVector32(0x1C, code16sel, (DWORD) (UINT) timer_handler);
  293.  
  294.     /* CTRL-C */
  295.     GetProtModeVector32(0x23, &ctrlcv.sel, &ctrlcv.off);
  296.     SetProtModeVector32(0x23, code16sel, (DWORD) (UINT) prot_cbrk);
  297.  
  298.     /* debug int3 */
  299.     if (!opt_debugrsx) {
  300.     GetProtModeVector32(0x03, &debintv.sel, &debintv.off);
  301.     SetProtModeVector32(0x03, code16sel, (DWORD) (UINT) debug_entry);
  302.     }
  303.     return 0;
  304. }
  305.  
  306. /*
  307. ** init fpu
  308. */
  309. int init_fpu(void)
  310. {
  311.     /* Get FPU status, if user allow this (not -e0) */
  312.     if (opt_force_copro != 1) {
  313.     if (DpmiGetCoproStatus(&fpu_status))
  314.         fpu_status = 0;
  315.     if (opt_printall)
  316.         printf("fpu_status = 0x%X\n", fpu_status);
  317.     }
  318.  
  319.     /*
  320.     ** copro = 0 , with -e option : if no 387, set copro = 2
  321.     ** copro = 1 , default : enable FPU
  322.     ** copro = 3 , if no FPU : enable kernel FPU emulation
  323.     */
  324.     if (copro == 0 && !npx_present)    /* catch missing 387 */
  325.     if (! opt_force_copro)
  326.         copro = 2;
  327.     if (copro) {
  328.     fpu_status_init = 1;
  329.     if (DpmiSetCoproStatus(copro))
  330.         puts("Warning: No DPMI-server FPU support");
  331.     }
  332.     return 0;
  333. }
  334.  
  335. static void free_emu_mem(void)
  336. {
  337.     UnlockLinRegion(RSX_PROCESS.memaddress, RSX_PROCESS.membytes);
  338.     if (rsx387_in_dosmem)
  339.     FreeDosMem((WORD) RSX_PROCESS.memhandle);
  340.     else
  341.     FreeMem(RSX_PROCESS.memhandle);
  342.     FreeLDT(RSX_PROCESS.code32sel);
  343.     FreeLDT(RSX_PROCESS.data32sel);
  344.     FreeLDT(RSX_PROCESS.data32sel + sel_incr);
  345. }
  346.  
  347. /* clean up interrupt handlers, exceptions, memory ... */
  348. void clean_up(void)
  349. {
  350.     flush_all_buffers();
  351.     clearregs();
  352.  
  353.     if (opt_printall)
  354.     puts("cleanup now");
  355.  
  356.     if (DPMIdata_para_needed)
  357.     UnlockLinRegion((DWORD) DPMIdata_segm_address << 4,
  358.             (DWORD) DPMIdata_para_needed << 4);
  359.  
  360.     /* unset 387-usage (otherwise: crash) */
  361.     if (fpu_status_init) {
  362.     DpmiSetCoproStatus(fpu_status & 3);
  363.     if (copro == 3 && emu_sel != 0)
  364.         free_emu_mem();
  365.     }
  366.     fpu_status_init = 0;
  367.     copro = 0;
  368.  
  369.     SetProtModeVector32(0x21, int21v.sel, int21v.off);
  370.     SetProtModeVector32(0x10, int10v.sel, int10v.off);
  371.     SetProtModeVector32(0x1C, timerv.sel, timerv.off);
  372.     SetProtModeVector32(0x23, ctrlcv.sel, ctrlcv.off);
  373.     SetProtModeVector32(0x03, debintv.sel, debintv.off);
  374.  
  375.     if (!opt_debugrsx) {
  376.     SetExceptionVector32(1, excep1v.sel, excep1v.off);
  377.     SetExceptionVector32(3, excep3v.sel, excep3v.off);
  378.     }
  379.     SetExceptionVector32(0, excep0v.sel, excep0v.off);
  380.     SetExceptionVector32(2, excep2v.sel, excep2v.off);
  381.     SetExceptionVector32(4, excep4v.sel, excep4v.off);
  382.     SetExceptionVector32(5, excep5v.sel, excep5v.off);
  383.     SetExceptionVector32(6, excep6v.sel, excep6v.off);
  384.     SetExceptionVector32(7, excep7v.sel, excep7v.off);
  385.     SetExceptionVector32(8, excep8v.sel, excep8v.off);
  386.     SetExceptionVector32(9, excep9v.sel, excep9v.off);
  387.     SetExceptionVector32(10, excep10v.sel, excep10v.off);
  388.     SetExceptionVector32(11, excep11v.sel, excep11v.off);
  389.     SetExceptionVector32(12, excep12v.sel, excep12v.off);
  390.     SetExceptionVector32(13, excep13v.sel, excep13v.off);
  391.     SetExceptionVector32(14, excep14v.sel, excep14v.off);
  392.     SetExceptionVector32(15, excep15v.sel, excep15v.off);
  393.     SetExceptionVector32(16, excep16v.sel, excep16v.off);
  394.     SetExceptionVector32(17, excep17v.sel, excep17v.off);
  395. }
  396.